package sg.edu.nus.iss.billing.gui.subscription;

import static sg.edu.nus.iss.billing.gui.subscription.UIConstants.CONTENT_H;
import static sg.edu.nus.iss.billing.gui.subscription.UIConstants.CONTENT_W;

import java.awt.BorderLayout;
import java.awt.Checkbox;
import java.awt.CheckboxGroup;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import sg.edu.nus.iss.billing.controller.AccountController;
import sg.edu.nus.iss.billing.controller.CustomerController;
import sg.edu.nus.iss.billing.controller.ServiceController;
import sg.edu.nus.iss.billing.controller.SubscriptionController;
import sg.edu.nus.iss.billing.entity.Customer;
import sg.edu.nus.iss.billing.entity.service.CableTVService;
import sg.edu.nus.iss.billing.entity.service.DigitalVoiceService;
import sg.edu.nus.iss.billing.entity.service.MobileVoiceService;
import sg.edu.nus.iss.billing.entity.service.PackageService;
import sg.edu.nus.iss.billing.entity.service.SubscriptionEntity;
import sg.edu.nus.iss.billing.exception.ControllerException;
import sg.edu.nus.iss.billing.exception.ValidationException;
import sg.edu.nus.iss.billing.gui.DefaultFunctionPanel;
import sg.edu.nus.iss.billing.gui.SessionContext;
import sg.edu.nus.iss.billing.gui.ViewCustomerAddressPanel;
import sg.edu.nus.iss.billing.gui.ViewCustomerContactPanel;
import sg.edu.nus.iss.billing.gui.ViewCustomerFieldPanel;
import sg.edu.nus.iss.billing.gui.ViewCustomerMiscPanel;
import sg.edu.nus.iss.billing.gui.component.ErrorDialog;
import sg.edu.nus.iss.billing.gui.component.ValidateJTextField;
import sg.edu.nus.iss.billing.localization.MessageKeyManager;
import sg.edu.nus.iss.billing.util.Util;
import sg.edu.nus.iss.billing.validation.ValidationRule;

public abstract class TabSubscriptionPanel extends DefaultFunctionPanel {

	private static final long serialVersionUID = 1L;

	private static int HEIGHT = 30;

	private JLabel lblCustHeader;

	private JLabel lblCustDetails;

	private CheckboxGroup cbg;

	private Checkbox ckNRIC;

	private Checkbox ckID;

	private Boolean ckState = true;

	private ValidateJTextField fieldinput;

	private JTabbedPane tabbedPane;

	private JPanel custInfoPanel;

	private JPanel searchPanel;

	private JPanel p;

	private JPanel tabPanel;

	// 4 panels to view customer's personal information
	private ViewCustomerFieldPanel custPanel;

	private ViewCustomerAddressPanel custAdd;

	private ViewCustomerContactPanel custContact;

	private ViewCustomerMiscPanel custMisc;

	private CustomerController customerController;

	private AccountController acctCtl;

	private SubscriptionController subscibeCtl;

	private ServiceController svcCtl;

	protected Customer cust;
	
	private boolean hasSubscription = true;

	protected String accNo;

	protected List<SubscriptionEntity> subscribedPakSvc;

	protected List<MobileVoiceService> mvSvc;

	protected List<DigitalVoiceService> dvSvc;

	protected List<CableTVService> tvSvc;

	protected SubcriptionPanel currentSelectedPanel;
	

	public TabSubscriptionPanel() {

		customerController = new CustomerController();
		acctCtl = new AccountController();
		subscibeCtl = new SubscriptionController();
		svcCtl = new ServiceController();
		cust = SessionContext.getCustomer();
		initUI();
	}
	
	private void initUI(){
		if(cust != null){
			super.init(null);
		} else {
			super.init("TOPONLY");
		}
	}

	public JPanel createTopPanel() {

		// Specify the top panel to display NRIC & Customer Account Number
		// search options
		searchPanel = new JPanel(null);

		lblCustHeader = new JLabel(MessageKeyManager.getMessage("label.custHeader"));
		Font f = new Font("Arial", Font.BOLD, 12);
		lblCustHeader.setFont(f);
		lblCustHeader.setBounds(10, 15, 200, HEIGHT);
		searchPanel.add(lblCustHeader);

		JPanel displayOptions = displaySearchOptions();
		displayOptions.setBounds(0, 25, CONTENT_W, 80);
		searchPanel.add(displayOptions);
		if(cust != null){
			fieldinput.setText(cust.getNRIC());
			fieldinput.updateUI();
		}
		return searchPanel;

	}

	private JPanel displaySearchOptions() {

		p = new JPanel(null);
		p.setPreferredSize(new Dimension(CONTENT_W, 80));

		lblCustDetails = new JLabel(MessageKeyManager.getMessage("label.custDetails"));
		lblCustDetails.setBounds(10, 15, 150, HEIGHT);
		p.add(lblCustDetails);

		cbg = new CheckboxGroup();
		ckNRIC = new Checkbox(MessageKeyManager.getMessage("label.nric"), true, cbg);
		ckNRIC.addItemListener(new checkBoxHandler());
		ckID = new Checkbox(MessageKeyManager.getMessage("label.custAcct"), false, cbg);
		ckID.addItemListener(new checkBoxHandler());
		ckNRIC.setBounds(180, 15, 250, HEIGHT);
		ckID.setBounds(450, 15, 250, HEIGHT);

		p.add(ckNRIC);
		p.add(ckID);

		fieldinput = new ValidateJTextField(MessageKeyManager.getMessage("label.NRIC/FIN"), ValidationRule.NOT_NULL, ValidationRule.NRIC);
		fieldinput.setBounds(180, 50, 250, 25);
		p.add(fieldinput);

		JButton lookupButton = new JButton(MessageKeyManager.getMessage("button.lookup"));
		lookupButton.setBounds(450, 50, 100, 25);
		lookupButton.addActionListener(new lookupListener());
		p.add(lookupButton);

		return p;
	}

	public JPanel createBottomPanel() {
		loadData();
		tabPanel = new JPanel();
		tabbedPane = new JTabbedPane();
		tabbedPane.setPreferredSize(new Dimension(CONTENT_W, CONTENT_H));
		custInfoPanel = createCustomerInfoPanel();
		tabbedPane.addTab("Customer Information ", custInfoPanel);
		SubcriptionPanel mobilePlanPanel = createMobilePlanPanel();
		SubcriptionPanel digitalPlanPanel = createDigitalPlanPanel();
		SubcriptionPanel cablePlanPanel = creaetCablePlanPanel();
		

		if (mobilePlanPanel==null&&digitalPlanPanel==null&&cablePlanPanel==null) {
			hasSubscription = false;
		}
		if (!hasSubscription) {
			JPanel tempPanel = new JPanel();
			tempPanel.setLayout(new BorderLayout());
			tempPanel.setPreferredSize(new Dimension(CONTENT_W, CONTENT_H));
			JTextArea info = new JTextArea(MessageKeyManager.getMessage("info.subs.nosubs"));
			info.setBackground(Color.WHITE);
			info.setEditable(false);
			tempPanel.add(info, BorderLayout.CENTER);
			tabbedPane.addTab(MessageKeyManager.getMessage("label.subs.info"), tempPanel);
			
		} else {
			if (mobilePlanPanel!=null) {
				tabbedPane.addTab(MessageKeyManager.getMessage("label.subs.mv"), mobilePlanPanel);
			}
			if (digitalPlanPanel!=null) {
				tabbedPane.addTab(MessageKeyManager.getMessage("label.subs.dv"), digitalPlanPanel);
			}
			if (cablePlanPanel!=null) {
				tabbedPane.addTab(MessageKeyManager.getMessage("label.subs.tv"), cablePlanPanel);
			}
		}
		tabbedPane.addChangeListener(new TabChangeHandler());
		tabPanel.add(tabbedPane);
		return tabPanel;

	}

	private JPanel createCustomerInfoPanel() {

		JPanel custInfoPanel = new JPanel();
		custInfoPanel.setPreferredSize(new Dimension(UIConstants.CONTENT_W, UIConstants.CONTENT_H));
		custInfoPanel.setLayout(new GridLayout(0, 2));

		custPanel = new ViewCustomerFieldPanel(cust);
		custAdd = new ViewCustomerAddressPanel(cust);
		custContact = new ViewCustomerContactPanel(cust);
		custMisc = new ViewCustomerMiscPanel(cust);

		custInfoPanel.add(custPanel);
		custInfoPanel.add(custAdd);
		custInfoPanel.add(custContact);
		custInfoPanel.add(custMisc);

		return custInfoPanel;
	}


	private class TabChangeHandler implements ChangeListener {

		@Override
		public void stateChanged(ChangeEvent e) {

			JTabbedPane tabbedPane = (JTabbedPane) e.getSource();
			JPanel panel = (JPanel) tabbedPane.getSelectedComponent();
			if (panel instanceof SubcriptionPanel) {
				currentSelectedPanel = (SubcriptionPanel) panel;
				if(getActionButtonPanel() != null) {
					getActionButtonPanel().setVisible(true);
				}
				
			} else {
				currentSelectedPanel = null;
				if(getActionButtonPanel() != null) {
					getActionButtonPanel().setVisible(false);
				}
			}
		}

	}
	
	private class checkBoxHandler implements ItemListener{


		@Override
		public void itemStateChanged(ItemEvent e) {
			Checkbox selectedCheckbox;
			selectedCheckbox = cbg.getSelectedCheckbox();
			if (selectedCheckbox==ckNRIC){
				fieldinput.setRules(ValidationRule.NOT_NULL, ValidationRule.NRIC);
				fieldinput.setFieldName(MessageKeyManager.getMessage("label.NRIC/FIN"));
				ckState = true;
			} else{
				fieldinput.setRules(ValidationRule.NOT_NULL);
				fieldinput.setFieldName(MessageKeyManager.getMessage("label.accountNo"));
				ckState = false;
			}
			
		}
		
	}

	private class lookupListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {

			try {
				String fieldCustNRICUpper = fieldinput.getText().toUpperCase();
				fieldinput.setText(fieldCustNRICUpper);
				if (ckState==true) {
					cust = customerController.getCustomerByNRIC(fieldinput.getValidatedText());
				} else {
					cust = customerController.getCustomerByAccount(fieldinput.getValidatedText());
				}
				
				if(cust == null){
					SessionContext.setCustomer(null);
					initUI();
				} else {
					SessionContext.setCustomer(cust);
					refreshBottomPanel();
					if(hasSubscription){
						refreshActionButtonPanel(createActionButtonsPanel());
					}
				}
				
			} catch (ValidationException ex) {
				ErrorDialog.showValidationErrorMessageDialog(ex);
			} catch (ControllerException ex){
				ErrorDialog.showControllerErrorMessageDialog(ex);
			}
		}
	}

	@SuppressWarnings("unchecked")
	private void loadData() {

		if (cust!=null) {
			try {
				this.accNo = acctCtl.getAccountByNRIC(cust.getNRIC()).getAccountNumber();
				this.subscribedPakSvc = subscibeCtl.getSubscribedPakSvcByAccNo(accNo);
				this.tvSvc = (List<CableTVService>) svcCtl.getAllPkgSvcs(new CableTVService());
				this.mvSvc = (List<MobileVoiceService>) svcCtl.getAllPkgSvcs(new MobileVoiceService());
				this.dvSvc = (List<DigitalVoiceService>) svcCtl.getAllPkgSvcs(new DigitalVoiceService());
			} catch (ControllerException e) {
				ErrorDialog.showControllerErrorMessageDialog(e);
			}
		}
	}

	protected boolean isSubscribeMobile() {

		boolean result = false;
		if (!Util.isEmpty(subscribedPakSvc)) {
			for (SubscriptionEntity sub : subscribedPakSvc) {
				for(PackageService svc:mvSvc){
					if(sub.getSvcId().equals(svc.getId())){
						result = true;
						break;
					}
				}
				
			}
		}
		return result;
	}

	protected boolean isSubscribeDigitalVoice() {

		boolean result = false;
		if (!Util.isEmpty(subscribedPakSvc)) {
			for (SubscriptionEntity sub : subscribedPakSvc) {
				
				for(PackageService svc:dvSvc){
					if(sub.getSvcId().equals(svc.getId())){
						result = true;
						break;
					}
				}
			}
		}
		return result;
	}

	protected boolean isSubscribeCableTV() {

		boolean result = false;
		if (!Util.isEmpty(subscribedPakSvc)) {
			for (SubscriptionEntity sub : subscribedPakSvc) {
				
				for(PackageService svc:tvSvc){
					if(sub.getSvcId().equals(svc.getId())){
						result = true;
						break;
					}
				}
			}
		}
		return result;
	}

	public abstract SubcriptionPanel createMobilePlanPanel();

	public abstract SubcriptionPanel createDigitalPlanPanel();

	public abstract SubcriptionPanel creaetCablePlanPanel();

}
